package com.yuanchu.store.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.store.client.FeignGoodsClient;
import com.yuanchu.store.client.FeignMediaClient;
import com.yuanchu.store.dao.YoshopPageDao;
import com.yuanchu.store.dto.*;
import com.yuanchu.store.entity.YoshopGoodsEntity;
import com.yuanchu.store.entity.YoshopPageEntity;
import com.yuanchu.store.service.YoshopPageService;
import com.yuanchu.store.utils.RedisUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service("yoshopPageService")
public class YoshopPageServiceImpl extends ServiceImpl<YoshopPageDao, YoshopPageEntity> implements YoshopPageService {


    @Resource
    private FeignGoodsClient feignGoodsClient;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private YoshopPageDao yoshopPageDao;
    @Resource
    private FeignMediaClient feignMediaClient;

    @Override
    public PageData getPageDetail(Integer pageId) {
        // 查询缓存
        String cacheKey = "shop:page";
        if (redisUtils.hasKey(cacheKey)) {
            return (PageData) redisUtils.get(cacheKey);
        }
        // 缓存不存在，从数据库中查询
        YoshopPageEntity page = this.getOne(new QueryWrapper<YoshopPageEntity>().eq("page_type", 10));
        PageData pageData = new PageData();
        String pageDataStr = page.getPageData();
        Map<String, Object> map = JSON.parseObject(pageDataStr, Map.class);
        Map<String, Object> pageMap = (Map<String, Object>) map.get("page");
        Page p = new Page();

        p.setName((String) pageMap.get("name"));
        p.setType((String) pageMap.get("type"));
        p.setParams((Map<String, Object>) pageMap.get("params"));
        p.setStyle((Map<String, Object>) pageMap.get("style"));
        pageData.setPage(p);
        JSONArray itemsJsonArray = (JSONArray) map.get("items");
        // List<Items> items = (List<Items>) map.get("items");
        // 创建一个Items对象列表来存储解析后的数据
        List<PageItems> items = new ArrayList<>();
        for (int i = 0; i < itemsJsonArray.size(); i++) {
            JSONObject itemJsonObj = itemsJsonArray.getJSONObject(i);
            PageItems item = JSON.toJavaObject(itemJsonObj, PageItems.class);

            if (item.getType().equals("goods") && "auto".equals(item.getParams().get("source"))) {
                JSONObject autoJsonObj = (JSONObject) item.getParams().get("auto");
                // goodsSort: sales all price 排序方式 sales:销量  all:全部 price:价格
                Integer categoryId = autoJsonObj.getInteger("category");
                String goodsSort = autoJsonObj.getString("goodsSort");
                Integer showNum = autoJsonObj.getInteger("showNum");

                // 调用FeignGoodsClient获取商品列表
                List<YoshopGoodsEntity> goodsEntities = feignGoodsClient.queryGoodsByCategoryId(categoryId);

                // 将商品实体转换为Map并添加到item的数据中
                List<Map<String, Object>> goodsList = new ArrayList<>();
                goodsEntities.forEach(goods -> {
                    // Map<String, Object> goodsMap = new HashMap<>();
                    GoodsData goodsData = new GoodsData();
                    goodsData.setGoods_id(goods.getGoodsId());
                    goodsData.setGoods_name(goods.getGoodsName());
                    goodsData.setGoods_image(goods.getGoodsImage());
                    goodsData.setGoods_sales(goods.getSalesActual());
                    goodsData.setSelling_point(goods.getSellingPoint());
                    goodsData.setGoods_price_min(String.valueOf(goods.getGoodsPriceMin()));
                    goodsData.setLine_price_min(String.valueOf(goods.getLinePriceMin()));
                    Map goodsMap = JSON.parseObject(JSON.toJSONString(goodsData), Map.class);
                    goodsList.add(goodsMap);
                });
                List<Map<String, Object>> datalist = null;
                if ("price".equals(goodsSort)) {
                    // Double.valueOf(o1.get("goods_price_min").toString()).compareTo(Double.valueOf(o2.get("goods_price_min").toString()))
                    datalist = goodsList.stream().sorted(Comparator.comparing(o -> Double.valueOf(o.get("goods_price_min").toString())))
                            .limit(showNum).collect(Collectors.toList());
                } else if ("sales".equals(goodsSort)) {
                    datalist = goodsList.stream().sorted((o1, o2) -> Integer.valueOf(o2.get("goods_sales").toString()).compareTo(Integer.valueOf(o1.get("goods_sales").toString())))
                            .limit(showNum).collect(Collectors.toList());
                } else {
                    //  if ("all".equals(goodsSort))
                    datalist = goodsList.stream().limit(showNum).collect(Collectors.toList());
                }
                item.setData(datalist);
            }

            items.add(item);
        }
        /*for (int i = 0; i < itemsJsonArray.size(); i++) {
            JSONObject itemJsonObj = itemsJsonArray.getJSONObject(i);
            Items item = JSON.toJavaObject(itemJsonObj, Items.class);
            items.add(item);
        }
        items.forEach(item -> {
            if (item.getType().equals("goods")) {
                // "source": "choice",手动获取  “auto”：自动获取
                String source = (String) item.getParams().get("source");
                if (source.equals("auto")) {
                    // 获取categoryId，根据categoryId获取商品列表
                    String autoStr = (String) item.getParams().get("auto");
                    Map map_auto = JSON.parseObject(autoStr, Map.class);
                    // 获取categoryId
                    Integer categoryId = (Integer) map_auto.get("category");
                    // 获取排序方式
                    String goodsSort = (String) map_auto.get("goodsSort");
                    // 调用FeignGoodsClient获取商品列表
                    List<YoshopGoodsEntity> goodsEntities = feignGoodsClient.queryGoodsByCategoryId(categoryId);
                    List<Map<String, Object>> goodsList = new ArrayList<>();
                    goodsEntities.forEach(goods ->{
                        Map<String, Object> goods_map = new HashMap<>();
                        BeanUtils.copyProperties(goods, goods_map);
                        goodsList.add(goods_map);
                    });
                    item.setData(goodsList);
                }
            }
        });*/

        pageData.setItems(items);

        // 添加缓存（一天）
        redisUtils.set(cacheKey, pageData);

        return pageData;
    }

    @Override
    public PageResult<YoshopPageEntity> queryPageList(QueryPageParams params, Integer storeId) {
        if (params == null){
            params = new QueryPageParams();
        }
        LambdaQueryWrapper<YoshopPageEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopPageEntity::getStoreId, storeId);
        lqw.like(StringUtils.isNotEmpty(params.getSearch()), YoshopPageEntity::getPageName, params.getSearch());
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<YoshopPageEntity> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
        List<YoshopPageEntity> records = this.page(page, lqw).getRecords();
        records.forEach(pageEntity -> {
            pageEntity.setCreateTime(DateFormatUtils.formatDatetime(pageEntity.getCreateTime()));
            pageEntity.setUpdateTime(DateFormatUtils.formatDatetime(pageEntity.getUpdateTime()));
        });
        return PageResult.formatPageResult(records, params.getPage(), params.getPagesize(), page.getTotal());
    }

    @Override
    public YoshopPageEntity queryPageDetail(Integer pageId) {
        YoshopPageEntity page = this.getById(pageId);
        PageData pageData = new PageData();
        String pageDataStr = page.getPageData();
        Map<String, Object> map = JSON.parseObject(pageDataStr, Map.class);
        Map<String, Object> pageMap = (Map<String, Object>) map.get("page");
        Page p = new Page();

        p.setName((String) pageMap.get("name"));
        p.setType((String) pageMap.get("type"));
        p.setParams((Map<String, Object>) pageMap.get("params"));
        p.setStyle((Map<String, Object>) pageMap.get("style"));
        pageData.setPage(p);
        JSONArray itemsJsonArray = (JSONArray) map.get("items");
        // List<Items> items = (List<Items>) map.get("items");
        // 创建一个Items对象列表来存储解析后的数据
        List<PageItems> items = new ArrayList<>();
        for (int i = 0; i < itemsJsonArray.size(); i++) {
            JSONObject itemJsonObj = itemsJsonArray.getJSONObject(i);
            PageItems item = JSON.toJavaObject(itemJsonObj, PageItems.class);

            if (item.getType().equals("goods") && "auto".equals(item.getParams().get("source"))) {
                JSONObject autoJsonObj = (JSONObject) item.getParams().get("auto");
                // goodsSort: sales all price 排序方式 sales:销量  all:全部 price:价格
                Integer categoryId = autoJsonObj.getInteger("category");
                String goodsSort = autoJsonObj.getString("goodsSort");
                Integer showNum = autoJsonObj.getInteger("showNum");

                // 调用FeignGoodsClient获取商品列表
                List<YoshopGoodsEntity> goodsEntities = feignGoodsClient.queryGoodsByCategoryId(categoryId);

                // 将商品实体转换为Map并添加到item的数据中
                List<Map<String, Object>> goodsList = new ArrayList<>();
                goodsEntities.forEach(goods -> {
                    // Map<String, Object> goodsMap = new HashMap<>();
                    GoodsData goodsData = new GoodsData();
                    goodsData.setGoods_id(goods.getGoodsId());
                    goodsData.setGoods_name(goods.getGoodsName());
                    goodsData.setGoods_image(goods.getGoodsImage());
                    goodsData.setGoods_sales(goods.getSalesActual());
                    goodsData.setSelling_point(goods.getSellingPoint());
                    goodsData.setGoods_price_min(String.valueOf(goods.getGoodsPriceMin()));
                    goodsData.setLine_price_min(String.valueOf(goods.getLinePriceMin()));
                    Map goodsMap = JSON.parseObject(JSON.toJSONString(goodsData), Map.class);
                    goodsList.add(goodsMap);
                });
                List<Map<String, Object>> datalist = null;
                if ("price".equals(goodsSort)) {
                    // Double.valueOf(o1.get("goods_price_min").toString()).compareTo(Double.valueOf(o2.get("goods_price_min").toString()))
                    datalist = goodsList.stream().sorted(Comparator.comparing(o -> Double.valueOf(o.get("goods_price_min").toString())))
                            .limit(showNum).collect(Collectors.toList());
                } else if ("sales".equals(goodsSort)) {
                    datalist = goodsList.stream().sorted((o1, o2) -> Integer.valueOf(o2.get("goods_sales").toString()).compareTo(Integer.valueOf(o1.get("goods_sales").toString())))
                            .limit(showNum).collect(Collectors.toList());
                } else {
                    //  if ("all".equals(goodsSort))
                    datalist = goodsList.stream().limit(showNum).collect(Collectors.toList());
                }
                item.setData(datalist);
            }

            items.add(item);
        }
        /*for (int i = 0; i < itemsJsonArray.size(); i++) {
            JSONObject itemJsonObj = itemsJsonArray.getJSONObject(i);
            Items item = JSON.toJavaObject(itemJsonObj, Items.class);
            items.add(item);
        }
        items.forEach(item -> {
            if (item.getType().equals("goods")) {
                // "source": "choice",手动获取  “auto”：自动获取
                String source = (String) item.getParams().get("source");
                if (source.equals("auto")) {
                    // 获取categoryId，根据categoryId获取商品列表
                    String autoStr = (String) item.getParams().get("auto");
                    Map map_auto = JSON.parseObject(autoStr, Map.class);
                    // 获取categoryId
                    Integer categoryId = (Integer) map_auto.get("category");
                    // 获取排序方式
                    String goodsSort = (String) map_auto.get("goodsSort");
                    // 调用FeignGoodsClient获取商品列表
                    List<YoshopGoodsEntity> goodsEntities = feignGoodsClient.queryGoodsByCategoryId(categoryId);
                    List<Map<String, Object>> goodsList = new ArrayList<>();
                    goodsEntities.forEach(goods ->{
                        Map<String, Object> goods_map = new HashMap<>();
                        BeanUtils.copyProperties(goods, goods_map);
                        goodsList.add(goods_map);
                    });
                    item.setData(goodsList);
                }
            }
        });*/

        pageData.setItems(items);
        page.setPage_data(pageData);
        page.setPageData(null);
        return page;
    }

    @Override
    public boolean setHomePage(Integer pageId) {
        String cacheKey = "shop:page";
        Integer integer = yoshopPageDao.setPageHome(pageId);
        if (integer > 0){
            // 删除缓存
            redisUtils.del(cacheKey);
            return true;
        }
        return false;
    }

    @Override
    public PageData queryPageDefaultData() {
        YoshopPageEntity page = this.getById("10004");
        PageData pageData = new PageData();
        String pageDataStr = page.getPageData();
        Map<String, Object> map = JSON.parseObject(pageDataStr, Map.class);
        Map<String, Object> pageMap = (Map<String, Object>) map.get("page");
        Page p = new Page();
        p.setName((String) pageMap.get("name"));
        p.setType((String) pageMap.get("type"));
        p.setParams((Map<String, Object>) pageMap.get("params"));
        p.setStyle((Map<String, Object>) pageMap.get("style"));
        pageData.setPage(p);
        pageData.setItems((Map<String, Object>) map.get("items"));
        return pageData;
    }

    @Override
    @Transactional
    public void editPage(StorePageParamsDto params) {
        Integer pageId = params.getPageId();
        boolean update = this.update(new UpdateWrapper<YoshopPageEntity>().eq("page_id", pageId)
                .set("page_data", JSON.toJSONString(params.getForm())));
        if (update) {
            // 删除缓存
            String cacheKey = "shop:page";
            redisUtils.del(cacheKey);
        }
    }

    @Override
    @Transactional
    public void addPage(StorePageParamsDto params) {
        YoshopPageEntity page = new YoshopPageEntity();
        page.setPageData(JSON.toJSONString(params.getForm()));
        page.setPageName(params.getForm().getPage().getParams().get("name").toString());
        page.setPageType(20);
        page.setStoreId(10001);
        page.setCreateTime(String.valueOf(System.currentTimeMillis()/1000));
        page.setUpdateTime(String.valueOf(System.currentTimeMillis()/1000));
        boolean save = this.save(page);
        if (!save){
            throw new YuanChuException("添加页面失败");
        }
    }

    @Override
    public void deletePage(Integer pageId) {
        YoshopPageEntity page = this.getById(pageId);
        if (page == null) {
            throw new YuanChuException("页面不存在");
        }
        boolean remove = this.removeById(pageId);
        if (remove) {
            // 删除缓存
            String cacheKey = "shop:page";
            redisUtils.del(cacheKey);
        }
    }
}